package com.tanhua.dubbo.api;

import com.tanhua.dubbo.api.mongo.UserLocationApi;
import com.tanhua.model.mongo.UserLocation;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户地址信息接口的实现类
 */
@DubboService
public class UserLocationApiImpl implements UserLocationApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存定位信息
     */
    @Override
    public void save(Long userId, Double latitude, Double longitude, String addrStr) {
        Query query = new Query(Criteria.where("userId").is(userId));
        UserLocation userLocation = mongoTemplate.findOne(query, UserLocation.class);
        GeoJsonPoint location = new GeoJsonPoint(longitude, latitude);
        long nowTime = System.currentTimeMillis();

        //若存在则更新
        if(null != userLocation) {
            Update update = new Update();
            update.set("location",location);
            update.set("address",addrStr);
            update.set("updated", nowTime);
            mongoTemplate.updateFirst(query, update, UserLocation.class);
        }else {
            //不存在则新增
            userLocation = new UserLocation();
            userLocation.setUserId(userId);
            userLocation.setLocation(location);
            userLocation.setAddress(addrStr);
            userLocation.setCreated(nowTime);
            userLocation.setUpdated(nowTime);
            mongoTemplate.insert(userLocation);
        }
    }

    /**
     * 搜索附近
     *
     * @param userId
     * @param distance
     * @return
     */
    @Override
    public List<Long> searchNearBy(Long userId, Long distance) {
        List<Long> ids = new ArrayList<>();
        Query query = new Query(Criteria.where("userId").is(userId));
        UserLocation userLocation = mongoTemplate.findOne(query, UserLocation.class);
        if(null == userLocation)
            return ids;

        Circle circle= new Circle(userLocation.getLocation(), new Distance(distance/1000, Metrics.KILOMETERS));
        Query nearQuery = new Query(Criteria.where("userId").ne(userId)
                .and("location").withinSphere(circle));
        List<UserLocation> userLocations = mongoTemplate.find(nearQuery, UserLocation.class);

        if(CollectionUtils.isNotEmpty(userLocations))
            ids =  userLocations.stream().map(UserLocation::getUserId).collect(Collectors.toList());

        return ids;
    }
}
